package cn.cdu.medical.controller;

import cn.cdu.basics.baseVo.PageVo;
import cn.cdu.basics.baseVo.Result;
import cn.cdu.basics.redis.RedisTemplateHelper;
import cn.cdu.basics.utils.PageUtil;
import cn.cdu.basics.utils.ResultUtil;
import cn.cdu.basics.utils.SecurityUtil;
import cn.cdu.data.entity.Role;
import cn.cdu.data.entity.User;
import cn.cdu.data.entity.UserRole;
import cn.cdu.data.service.IRoleService;
import cn.cdu.data.service.IUserRoleService;
import cn.cdu.data.service.IUserService;
import cn.cdu.data.utils.NullUtils;
import cn.cdu.medical.service.MedicalRecordService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 患者接口
 */
@Slf4j
@RestController
@Tag(name = "患者接口")
@RequestMapping("/zwz/patients")
@CrossOrigin(origins = "*", maxAge = 3600)
@Transactional
public class PatientController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private SecurityUtil securityUtil;

    @PersistenceContext
    private EntityManager entityManager;
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @Autowired
    private RedisTemplateHelper redisTemplateHelper;
    
    @Autowired
    private org.springframework.context.ApplicationContext applicationContext;

    /**
     * 获取患者角色ID
     */
    private String getPatientRoleId() {
        QueryWrapper<Role> roleQw = new QueryWrapper<>();
        roleQw.eq("name", "ROLE_PATIENT");
        Role patientRole = roleService.getOne(roleQw);
        if (patientRole != null) {
            return patientRole.getId();
        }
        
        log.warn("未找到患者角色(ROLE_PATIENT)");
        return null;
    }

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @Operation(summary = "搜索患者")
    public Result<List<Map<String, Object>>> searchPatients(@RequestParam(required = false) String keyword) {
        log.info("搜索患者接口被调用，关键词: {}", keyword);
        
        // 获取患者角色ID
        String patientRoleId = getPatientRoleId();
        List<User> users = new ArrayList<>();
        
        try {
            if (patientRoleId != null) {
                log.info("患者角色ID: {}", patientRoleId);
                
                // 获取有患者角色的用户ID
                QueryWrapper<UserRole> userRoleQw = new QueryWrapper<>();
                userRoleQw.eq("role_id", patientRoleId);
                userRoleQw.eq("del_flag", 0);
                List<UserRole> userRoles = userRoleService.list(userRoleQw);
                
                log.info("找到 {} 个患者角色关联记录", userRoles == null ? 0 : userRoles.size());
                
                if (userRoles != null && !userRoles.isEmpty()) {
                    // 构建查询条件
                    QueryWrapper<User> userQw = new QueryWrapper<>();
                    List<String> userIds = userRoles.stream().map(UserRole::getUserId).collect(Collectors.toList());
                    userQw.in("id", userIds);
                    
                    // 如果有关键字，添加搜索条件
                    if (keyword != null && !keyword.trim().isEmpty()) {
                        userQw.and(wrapper -> wrapper
                            .like("username", keyword)
                            .or()
                            .like("nickname", keyword)
                            .or()
                            .like("mobile", keyword)
                        );
                    }
                    
                    // 查询用户
                    users = userService.list(userQw);
                    log.info("通过角色关联找到 {} 名患者", users.size());
                } else {
                    log.warn("未找到任何患者角色关联数据，将尝试备用方法查询");
                }
            } else {
                log.warn("未找到患者角色(ROLE_PATIENT)，将使用备用方法查询患者");
            }
            
            // 如果通过角色没有找到患者，尝试查询type=0的用户作为备选
            if (users.isEmpty()) {
                log.info("使用备用方法查询患者 (type=0的用户)");
                QueryWrapper<User> userQw = new QueryWrapper<>();
                userQw.eq("type", 0);
                userQw.eq("del_flag", 0);
                
                // 如果有关键字，添加搜索条件
                if (keyword != null && !keyword.trim().isEmpty()) {
                    userQw.and(wrapper -> wrapper
                        .like("username", keyword)
                        .or()
                        .like("nickname", keyword)
                        .or()
                        .like("mobile", keyword)
                    );
                }
                
                // 限制返回数量
                userQw.last("LIMIT 20");
                
                users = userService.list(userQw);
                log.info("通过type=0查询找到 {} 名患者", users.size());
            }
            
            // 转换为前端需要的格式
            List<Map<String, Object>> result = users.stream().map(user -> {
                Map<String, Object> map = new HashMap<>();
                map.put("id", user.getId());
                map.put("name", user.getNickname());
                map.put("gender", user.getSex());
                map.put("age", ""); // 年龄需要从生日计算，暂时留空
                map.put("phone", user.getMobile());
                map.put("fileNumber", "P" + user.getId().substring(Math.max(0, user.getId().length() - 8))); // 生成一个档案号
                return map;
            }).collect(Collectors.toList());
            
            log.info("最终返回 {} 名患者记录", result.size());
            return new ResultUtil<List<Map<String, Object>>>().setData(result);
        } catch (Exception e) {
            log.error("搜索患者失败", e);
            return new ResultUtil<List<Map<String, Object>>>().setErrorMsg("搜索患者失败: " + e.getMessage());
        }
    }
    
    @RequestMapping(value = "/page", method = RequestMethod.GET)
    @Operation(summary = "分页获取患者列表")
    public Result<IPage<Map<String, Object>>> getPatientList(@ModelAttribute PageVo page) {
        log.info("分页获取患者列表，页码: {}, 每页大小: {}", page.getPageNumber(), page.getPageSize());
        
        // 获取患者角色ID
        String patientRoleId = getPatientRoleId();
        
        try {
            QueryWrapper<User> userQw = new QueryWrapper<>();
            
            if (patientRoleId != null) {
                log.info("患者角色ID: {}", patientRoleId);
                
                // 获取有患者角色的用户ID
                QueryWrapper<UserRole> userRoleQw = new QueryWrapper<>();
                userRoleQw.eq("role_id", patientRoleId);
                userRoleQw.eq("del_flag", 0);
                List<UserRole> userRoles = userRoleService.list(userRoleQw);
                
                log.info("找到 {} 个患者角色关联记录", userRoles == null ? 0 : userRoles.size());
                
                if (userRoles != null && !userRoles.isEmpty()) {
                    List<String> userIds = userRoles.stream().map(UserRole::getUserId).collect(Collectors.toList());
                    userQw.in("id", userIds);
                } else {
                    log.warn("未找到任何患者角色关联数据，将查询type=0的用户作为患者");
                    userQw.eq("type", 0);
                    userQw.eq("del_flag", 0);
                }
            } else {
                log.warn("未找到患者角色(ROLE_PATIENT)，将查询type=0的用户作为患者");
                userQw.eq("type", 0);
                userQw.eq("del_flag", 0);
            }
            
            IPage<User> userPage = userService.page(PageUtil.initMpPage(page), userQw);
            
            // 转换为前端需要的格式
            IPage<Map<String, Object>> resultPage = userPage.convert(user -> {
                Map<String, Object> map = new HashMap<>();
                map.put("id", user.getId());
                map.put("name", user.getNickname());
                map.put("gender", user.getSex());
                map.put("age", ""); // 年龄需要从生日计算，暂时留空
                map.put("phone", user.getMobile());
                map.put("fileNumber", "P" + user.getId().substring(Math.max(0, user.getId().length() - 8))); // 生成一个档案号
                return map;
            });
            
            log.info("分页查询到 {} 名患者", resultPage.getRecords().size());
            return new ResultUtil<IPage<Map<String, Object>>>().setData(resultPage);
        } catch (Exception e) {
            log.error("分页获取患者列表失败", e);
            return new ResultUtil<IPage<Map<String, Object>>>().setErrorMsg("分页获取患者列表失败: " + e.getMessage());
        }
    }
    
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @Operation(summary = "获取患者详情")
    public Result<Map<String, Object>> getPatientDetail(@PathVariable String id) {
        log.info("获取患者详情，ID: {}", id);
        
        try {
            User user = userService.getById(id);
            if (user == null) {
                log.error("患者不存在，ID: {}", id);
                return new ResultUtil<Map<String, Object>>().setErrorMsg("患者不存在");
            }
            
            // 检查是否有患者角色
            String patientRoleId = getPatientRoleId();
            QueryWrapper<UserRole> userRoleQw = new QueryWrapper<>();
            userRoleQw.eq("user_id", id);
            userRoleQw.eq("role_id", patientRoleId);
            userRoleQw.eq("del_flag", 0);
            long count = userRoleService.count(userRoleQw);
            
            if (count == 0) {
                log.error("用户不是患者，ID: {}", id);
                return new ResultUtil<Map<String, Object>>().setErrorMsg("用户不是患者");
            }
            
            // 转换为前端需要的格式
            Map<String, Object> result = new HashMap<>();
            result.put("id", user.getId());
            result.put("name", user.getNickname());
            result.put("gender", user.getSex());
            result.put("age", ""); // 年龄需要从生日计算，暂时留空
            result.put("phone", user.getMobile());
            result.put("fileNumber", "P" + user.getId().substring(Math.max(0, user.getId().length() - 8))); // 生成一个档案号
            result.put("email", user.getEmail());
            result.put("address", user.getAddress());
            
            log.info("获取患者详情成功，ID: {}", id);
            return new ResultUtil<Map<String, Object>>().setData(result);
        } catch (Exception e) {
            log.error("获取患者详情失败", e);
            return new ResultUtil<Map<String, Object>>().setErrorMsg("获取患者详情失败: " + e.getMessage());
        }
    }

    @RequestMapping(value = "/records", method = RequestMethod.GET)
    @Operation(summary = "获取患者的挂号-病历关联记录")
    public Result<List<Map<String, Object>>> getPatientOrderRecords(@PathVariable String patientId) {
        log.info("获取患者的挂号-病历关联记录，患者ID: {}", patientId);
        
        try {
            // 检查医生是否有权限查看该患者病历
            // TODO: 添加权限检查逻辑
            
            // 注入MedicalRecordService
            if (applicationContext == null) {
                return new ResultUtil<List<Map<String, Object>>>().setErrorMsg("系统服务未准备好");
            }
            
            MedicalRecordService medicalRecordService = applicationContext.getBean(MedicalRecordService.class);
            if (medicalRecordService == null) {
                return new ResultUtil<List<Map<String, Object>>>().setErrorMsg("病历服务不可用");
            }
            
            // 获取关联记录
            List<Map<String, Object>> records = medicalRecordService.getPatientOrderRecords(patientId);
            
            return new ResultUtil<List<Map<String, Object>>>().setData(records);
        } catch (Exception e) {
            log.error("获取患者挂号-病历关联记录失败", e);
            return new ResultUtil<List<Map<String, Object>>>().setErrorMsg("获取患者挂号-病历关联记录失败: " + e.getMessage());
        }
    }
} 